#region - Class details -
/*  
 *  Developer   : Wicus Botha
 *  Description : 
 *  History     : WB - 2008-02-08 - Created
 */
#endregion

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace IQ.BaseWindows
{
	/// <summary>
	/// Description of Class1.
	/// </summary>
	public static class DataBind 
	{
		//#region - Private variables -
		//#endregion
		
		#region - Private methods -
        private static void bindComboBoxOptionsDictionary(ComboBox cbxBind, object keyValue)
        {
            cbxBind.DisplayMember = "Value";
            cbxBind.ValueMember = "Key";
            cbxBind.DataSource = new BindingSource(keyValue, null);
        }
        private static void bindGridComboBoxOptionsDictionary(DataGridViewComboBoxColumn cbxBind, object keyValue)
        {
            cbxBind.DisplayMember = "Value";
            cbxBind.ValueMember = "Key";
            cbxBind.DataSource = new BindingSource(keyValue, null);
        }

        #endregion
	
		//#region - Public properties / variables -
		//#endregion

		#region - Public methods - 
        /// <summary>
        /// Bind ComboBox list options to a lookup datasource
        /// </summary>
        /// <param name="cbxBind">ComboBox to use</param>
        /// <param name="dataSource">Lookup data source</param>
        /// <param name="displayField">Display field</param>
        /// <param name="valueField">Value field</param>
		public static void BindComboBoxOptions(ComboBox cbxBind, object dataSource,
                                        string displayField, string valueField)
        {
            cbxBind.DisplayMember   = displayField;
            cbxBind.ValueMember     = valueField;
            cbxBind.DataSource      = dataSource;
            //cbxBind.DataBindings.Clear();
            //cbxBind.DataBindings.Add("SelectedValue", dataSource, itemValue);
        }
        public static void BindComboBoxOptions(ComboBox cbxBind, Dictionary<int, string> keyValue)
        {
            bindComboBoxOptionsDictionary(cbxBind, keyValue);
        }
        public static void BindComboBoxOptions(ComboBox cbxBind, Dictionary<byte, string> keyValue)
        {
            bindComboBoxOptionsDictionary(cbxBind, keyValue);
        }
        public static void BindComboBoxOptions(ComboBox cbxBind, Dictionary<short, string> keyValue)
        {
            bindComboBoxOptionsDictionary(cbxBind, keyValue);
        }
        public static void BindComboBoxOptions(ComboBox cbxBind, Dictionary<char, string> keyValue)
        {
            bindComboBoxOptionsDictionary(cbxBind, keyValue);
        }
        public static void BindComboBoxOptions(ComboBox cbxBind, Dictionary<string, string> keyValue)
        {
            bindComboBoxOptionsDictionary(cbxBind, keyValue);
        }
        public static void BindComboBoxOptionsCode(ComboBox cbxBind, object dataSource)
        {
            BindComboBoxOptions(cbxBind, dataSource, "CodeDesc", "CodeId");
        }

        public static void BindComboBoxOptionsStatus(ComboBox cbxBind, object dataSource)
        {
            BindComboBoxOptions(cbxBind, dataSource, "StatusDesc", "Status");
        }

        public static void BindComboBoxOptionsLookup(ComboBox cbxBind, object dataSource)
        {
            BindComboBoxOptions(cbxBind, dataSource, "ItemDesc", "ItemId");
        }
        public static void BindComboBoxValue(ComboBox cbxBind, int value)
        {
            cbxBind.SelectedValue = value;
            if (cbxBind.Items.Count > 0 && cbxBind.SelectedIndex < 0)
                cbxBind.SelectedIndex = 0;
        }
        // Grid ComboBoxes
        public static void BindGridComboBoxOptions(DataGridViewComboBoxColumn cbxBind, object dataSource, string displayField, string valueField)
        {
            cbxBind.DisplayMember = displayField;
            cbxBind.ValueMember = valueField;
            cbxBind.DataSource = dataSource;
        }
        public static void BindGridComboBoxOptionsLookup(DataGridViewComboBoxColumn cbxBind, object dataSource)
        {
            BindGridComboBoxOptions(cbxBind, dataSource, "ItemDesc", "ItemId");
        }
        public static void BindGridComboBoxOptionsCode(DataGridViewComboBoxColumn cbxBind, object dataSource)
        {
            BindGridComboBoxOptions(cbxBind, dataSource, "CodeDesc", "CodeId");
        }
        public static void BindGridComboBoxOptionsStatus(DataGridViewComboBoxColumn cbxBind, object dataSource)
        {
            BindGridComboBoxOptions(cbxBind, dataSource, "StatusDesc", "Status");
        }
        public static void BindGridComboBoxOptions(DataGridViewComboBoxColumn cbxBind, Dictionary<int, string> keyValue)
        {
            bindGridComboBoxOptionsDictionary(cbxBind, keyValue);
        }
        public static void BindGridComboBoxOptions(DataGridViewComboBoxColumn cbxBind, Dictionary<byte, string> keyValue)
        {
            bindGridComboBoxOptionsDictionary(cbxBind, keyValue);
        }
        public static void BindGridComboBoxOptions(DataGridViewComboBoxColumn cbxBind, Dictionary<short, string> keyValue)
        {
            bindGridComboBoxOptionsDictionary(cbxBind, keyValue);
        }
        public static void BindGridComboBoxOptions(DataGridViewComboBoxColumn cbxBind, Dictionary<char, string> keyValue)
        {
            bindGridComboBoxOptionsDictionary(cbxBind, keyValue);
        }
        public static void BindGridComboBoxOptions(DataGridViewComboBoxColumn cbxBind, Dictionary<string, string> keyValue)
        {
            bindGridComboBoxOptionsDictionary(cbxBind, keyValue);
        }

        /// <summary>
        /// Bind ComboBox list options to a destination object
        /// </summary>
        /// <param name="cbxBind">ComboBox to use</param>
        /// <param name="destination">Destination object</param>
        /// <param name="valueField">Value field</param>
        public static void BindComboBoxToField(ComboBox cbxBind, object destination, string valueField)
        {
            cbxBind.DataBindings.Clear();
            cbxBind.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
            cbxBind.DataBindings.Add("SelectedValue", destination, valueField);
        }

        /// <summary>
        /// Bind ComboBox index to a destination object
        /// </summary>
        /// <param name="cbxBind">ComboBox to use</param>
        /// <param name="destination">Destination object</param>
        /// <param name="valueField">Value field</param>
        public static void BindComboBoxIndexToField(ComboBox cbxBind, object destination, string valueField)
        {
            cbxBind.DataBindings.Clear();
            cbxBind.DataBindings.Add("SelectedIndex", destination, valueField);
        }

        public static void BindControl(Control control, string property, object destination, string valueField)
        {
            control.DataBindings.Clear();
            control.DataBindings.Add(property, destination, valueField, true, DataSourceUpdateMode.OnPropertyChanged);
        }
        public static void BindCheckBox(CheckBox ckbBind, object destination, string valueField)
        {
            ckbBind.DataBindings.Clear();
            ckbBind.DataBindings.Add("Checked", destination, valueField, true, DataSourceUpdateMode.OnPropertyChanged);
        }

        public static void BindCheckBoxIndexToField(CheckBox ckbBind, object destination, string valueField)
        {
            ckbBind.DataBindings.Clear();
            ckbBind.DataBindings.Add("Checked", destination, valueField, true, DataSourceUpdateMode.OnPropertyChanged);
        }

        public static void BindNumericUpDown(NumericUpDown nudBind, object destination, string valueField)
        {
            nudBind.DataBindings.Clear();
            nudBind.DataBindings.Add("Value", destination, valueField, true, DataSourceUpdateMode.OnPropertyChanged);
        }
        /// <summary>
        /// Bind TextBox to datasource 
        /// </summary>
        /// <param name="txtBind">TextBox to bind</param>
        /// <param name="dataSource">Datasource to use</param>
        /// <param name="fieldName">Field to use</param>
        public static void BindRichTextBox(RichTextBox txtBind, object dataSource, string fieldName)
        {
            BindTextBox(txtBind, dataSource, fieldName);
        }

        /// <summary>
        /// Bind TextBoxBase to datasource 
        /// </summary>
        /// <param name="txtBind">TextBox to bind</param>
        /// <param name="dataSource">Datasource to use</param>
        /// <param name="fieldName">Field to use</param>
        public static void BindTextBox(TextBoxBase txtBind, object dataSource, string fieldName)
        {
            txtBind.DataBindings.Clear();
            txtBind.DataBindings.Add("Text", dataSource, fieldName, true, DataSourceUpdateMode.OnPropertyChanged);
        }
        public static void BindTextBox(TextBox txtBind, object dataSource, string fieldName)
        {
            txtBind.DataBindings.Clear();
            txtBind.DataBindings.Add("Text", dataSource, fieldName, true, DataSourceUpdateMode.OnPropertyChanged);
        }
        public static void BindTextBox(MaskedTextBox txtBind, object dataSource, string fieldName)
        {
            txtBind.DataBindings.Clear();
            txtBind.DataBindings.Add("Text", dataSource, fieldName, true, DataSourceUpdateMode.OnPropertyChanged);
        }
        /// <summary>
        /// Bind TextBox to datasource and format data to number
        /// </summary>
        /// <param name="txtBind">TextBox to bind</param>
        /// <param name="dataSource">Datasource to use</param>
        /// <param name="fieldName">Field to use</param>
        public static void BindTextBoxNumber(TextBox txtBind, object dataSource, string fieldName)
        {
            txtBind.DataBindings.Clear();
            txtBind.DataBindings.Add("Text", dataSource, fieldName, true, DataSourceUpdateMode.OnPropertyChanged, null, "#0");
        }

        /// <summary>
        /// Bind TextBox to datasource and format data to decimal i.e. 21200.36
        /// </summary>
        /// <param name="txtBind">TextBox to bind</param>
        /// <param name="dataSource">Datasource to use</param>
        /// <param name="fieldName">Field to use</param>
        public static void BindTextBoxDecimal(TextBox txtBind, object dataSource, string fieldName)
        {
            txtBind.DataBindings.Clear();
            txtBind.DataBindings.Add("Text", dataSource, fieldName, true, DataSourceUpdateMode.OnPropertyChanged, null, "F");//#0.00
        }

        /// <summary>
        /// Bind TextBox to datasource and format data to curreny i.e. R21 200.36
        /// </summary>
        /// <param name="txtBind">TextBox to bind</param>
        /// <param name="dataSource">Datasource to use</param>
        /// <param name="fieldName">Field to use</param>
        public static void BindTextBoxMoney(TextBox txtBind, object dataSource, string fieldName)
        {
            txtBind.DataBindings.Clear();
            txtBind.DataBindings.Add("Text", dataSource, fieldName, true, DataSourceUpdateMode.OnPropertyChanged, null, "C");
        }

        /// <summary>
        /// Bind TextBox to datasource 
        /// </summary>
        /// <param name="lblBind">TextBox to bind</param>
        /// <param name="dataSource">Datasource to use</param>
        /// <param name="fieldName">Field to use</param>
        public static void BindLabel(Label lblBind, object dataSource, string fieldName)
        {
            lblBind.DataBindings.Clear();
            lblBind.DataBindings.Add("Text", dataSource, fieldName);
        }

        /// <summary>
        /// Bind DateTimePicker to datasource 
        /// </summary>
        /// <param name="dtpBind">DateTimePicker to bind</param>
        /// <param name="dataSource">Datasource to use</param>
        /// <param name="fieldName">Field to use</param>
        public static void BindDateTimePicker(DateTimePicker dtpBind, object dataSource, string fieldName)
        {
            dtpBind.DataBindings.Clear();
            dtpBind.DataBindings.Add("Value", dataSource, fieldName, true, DataSourceUpdateMode.OnPropertyChanged);
        }

        /// <summary>
        /// Bind DateTimePicker to datasource 
        /// </summary>
        /// <param name="dtpBind">DateTimePicker to bind</param>
        /// <param name="dataSource">Datasource to use</param>
        /// <param name="fieldName">Field to use</param>
        /// <param name="dateOnly">Date only, don't show time</param>
        private static void Bind_DTP_Nullable(DateTimePicker dtpBind, object dataSource, string fieldName, bool dateOnly)
        {
            Binding binding = new Binding("Value", dataSource, fieldName, true, DataSourceUpdateMode.OnPropertyChanged);
            //OBJECT PROPERTY --> CONTROL VALUE
            binding.Format += new ConvertEventHandler((sender, e) =>
            {
                Binding b = sender as Binding;
                if (b != null)
                {
                    DateTimePicker dtp = (binding.Control as DateTimePicker);
                    if (dtp != null)
                    {
                        if (e.Value == null)
                        {
                            dtp.ShowCheckBox = true;
                            dtp.Checked = false; 
                            // have to set e.Value to SOMETHING, since it's coming in as NULL
                            // if i set to DateTime.Today, and that's DIFFERENT than the control's current
                            // value, then it triggers a CHANGE to the value, which CHECKS the box (not ok)
                            // the trick - set e.Value to whatever value the control currently has. 
                            // This does NOT cause a CHANGE, and the checkbox stays OFF. 
                            e.Value = dtp.Value; 
                        }
                        else
                        {
                            dtp.ShowCheckBox = true;
                            dtp.Checked = true;
                            // leave e.Value unchanged - it's not null, so the DTP is fine with it.
                        } 
                    } 
                }
            });
            // CONTROL VALUE --> OBJECT PROPERTY
            binding.Parse += new ConvertEventHandler((sender, e) => 
            {
                // e.value is the formatted value coming from the control. 
                // we change it to be the value we want to stuff in the object.
                Binding b = sender as Binding; 
                if (b != null)
                {
                    DateTimePicker dtp = (b.Control as DateTimePicker);
                    if (dtp != null)
                    {
                        if (dtp.Checked == false)
                        {
                            dtp.ShowCheckBox = true;
                            dtp.Checked = false;
                            e.Value = (Nullable<DateTime>) null;
                        }
                        else
                        {
                            DateTime val = Convert.ToDateTime(e.Value);
                            if (dateOnly)
                                e.Value = val.Date;
                            else
                                e.Value = val;
                        }
                    }
                }
            }
            );
            dtpBind.DataBindings.Clear();
            dtpBind.DataBindings.Add(binding);
        }

        /// <summary>
        /// Bind DateTimePicker to datasource 
        /// </summary>
        /// <param name="dtpBind">DateTimePicker to bind</param>
        /// <param name="dataSource">Datasource to use</param>
        /// <param name="fieldName">Field to use</param>

        public static void BindDateTimePickerNullable(DateTimePicker dtpBind, object dataSource, string fieldName)
        {
            Bind_DTP_Nullable(dtpBind, dataSource, fieldName, false);
        }

        /// <summary>
        /// Bind DateTimePicker to datasource 
        /// </summary>
        /// <param name="dtpBind">DateTimePicker to bind</param>
        /// <param name="dataSource">Datasource to use</param>
        /// <param name="fieldName">Field to use</param>
        public static void BindDatePickerNullable(DateTimePicker dtpBind, object dataSource, string fieldName)
        {
            Bind_DTP_Nullable(dtpBind, dataSource, fieldName, true);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="lstBind"></param>
        /// <param name="dataSource"></param>
        /// <param name="itemDescription"></param>
        /// <param name="itemValue"></param>
        public static void BindListBox(ListBox lstBind, object dataSource,
                                        string itemDescription, string itemValue)
        {
            lstBind.DisplayMember = itemDescription;
            lstBind.ValueMember = itemValue;
            lstBind.DataSource = dataSource;
        }
        public static void BindCheckedListBox(CheckedListBox clbBind, Dictionary<int, string> dataSource)
        {
            BindingSource bs = new BindingSource(dataSource, null);
            if (dataSource.Count > 0)
            {
                clbBind.DataSource = bs;
                clbBind.DisplayMember = "Value";
                clbBind.ValueMember = "Key";
            }
        }
		#endregion
	}
}
